home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
utils
/
nroff~06.zoo
/
low.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-16
|
17KB
|
1,102 lines
static char *rcsid_low_c="$Id: low.c,v 1.2 1992/07/16 10:38:32 rosenkra Exp $";
/*
* $Log: low.c,v $
* Revision 1.2 1992/07/16 10:38:32 rosenkra
* port to gcc, add tm,ie,el
*
*/
/*
* low.c - misc low-level functions for nroff word processor
*
* adapted for atariST/TOS by Bill Rosenkranz 11/89
* net: rosenkra@convex.com
* CIS: 71460,17
* GENIE: W.ROSENKRANZ
*
* original author:
*
* Stephen L. Browning
* 5723 North Parker Avenue
* Indianapolis, Indiana 46220
*
* history:
*
* - Originally written in BDS C;
* - Adapted for standard C by W. N. Paul
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* atod */
/*------------------------------*/
int atod (c)
char c;
{
/*
* convert ascii character to decimal.
*/
return (((c < '0') || (c > '9')) ? -1 : c - '0');
}
/*------------------------------*/
/* robrk */
/*------------------------------*/
void robrk ()
{
/*
* end current filled line
*/
REGISTER char *p, *p0;
if (co.outp > 0)
{
/*
* kill trailing blanks....
*/
p0 = &(co.outbuf[0]);
p = &(co.outbuf[co.outp]);
for (p--; (long) p > (long) p0; p--)
{
if (*p != ' ' && *p != '\t')
break;
co.outp -= 1;
}
/*
* terminate line
*/
#ifdef NO_CR
co.outbuf[co.outp] = '\n';
co.outbuf[co.outp+1] = EOS;
#else
co.outbuf[co.outp] = '\r';
co.outbuf[co.outp+1] = '\n';
co.outbuf[co.outp+2] = EOS;
#endif
/*
* handle margin char (change bar) here for all filled lines
*/
do_mc (co.outbuf);
put (co.outbuf);
}
co.outp = 0;
co.outw = 0;
co.outwds = 0;
co.outesc = 0;
}
/*------------------------------*/
/* ctod */
/*------------------------------*/
int ctod (p)
REGISTER char *p;
{
/*
* convert string to decimal. processes only positive values.
* this takes a constant like "1", "1.0i", etc.
*/
REGISTER long val;
REGISTER int d;
REGISTER char *pp = p;
REGISTER char *ptmp;
int rside = 0;
int lside = 0;
int has_rside = 0;
int has_lside = 0;
if (*p == EOS)
return (0);
ptmp = skipwd (pp);
pp = --ptmp;
switch (*pp)
{
case 'i':
case 'c':
val = 0L;
while (*p != EOS && isdigit (*p))
{
has_lside++;
lside = atod (*p);
p++;
if (lside == -1)
break;
val = 10L * val + (long) lside;
}
lside = (int) val;
if (*p == '.')
{
p++;
val = 0L;
while (*p != EOS && isdigit (*p))
{
has_rside++;
rside = atod (*p);
p++;
if (rside == -1)
break;
val = 10L * val + (long) rside;
if (has_rside > 2) /* more than enough */
break;
}
rside = (int) val;
}
/*
* now put it together. 1.0i -> 240, 1.50i -> 360, etc.
*/
val = 0L;
if (has_lside)
{
val = (long) lside * BU_INCH;
}
switch (has_rside)
{
case 1:
val = val + ((long) rside * BU_INCH / 10L);
break;
case 2:
val = val + ((long) rside * BU_INCH / 100L);
break;
case 3:
val = val + ((long) rside * BU_INCH / 1000L);
break;
default:
break;
}
if (*pp == 'c')
val = (val * BU_CM) / BU_INCH;
/*
* for now we convert to basic char size, 1 em...
*/
val = val / BU_EM;
break;
case 'P':
case 'm':
case 'n':
case 'p':
case 'u':
case 'v':
val = 0L;
while (*p != EOS)
{
d = atod (*p);
p++;
if (d == -1)
break;
val = 10L * val + (long) d;
}
switch (*pp)
{
case 'P':
val = val * BU_PICA;
break;
case 'p':
val = val * BU_POINT;
break;
case 'u':
val = val * BU_BU;
break;
case 'm':
val = val * BU_EM;
break;
case 'n':
val = val * BU_EN;
break;
case 'v':
val = val * BU_EM;
break;
}
/*
* for now we convert to basic char size, 1 em...
*/
val = val / BU_EM;
break;
default:
/*
* this is the default behavior. it SHOULD make things
* compatible with the old way...
*/
val = 0L;
while (*p != EOS)
{
d = atod (*p);
p++;
if (d == -1)
break;
val = 10L * val + (long) d;
}
break;
}
return ((int) val);
}
/*------------------------------*/
/* inptobu */
/*------------------------------*/
void inptobu (ps)
char *ps;
{
/*
* convert input units to b.u.
*/
return;
}
/*------------------------------*/
/* butochar */
/*------------------------------*/
void butochar (ps)
char *ps;
{
/*
* convert b.u. to char spaces
*/
return;
}
/*------------------------------*/
/* skipbl */
/*------------------------------*/
char *skipbl (p)
REGISTER char *p;
{
/*
* skip blanks and tabs in character buffer. return ptr to first
* non-space or non-tab char. this could mean EOS or \r or \n.
* also increments the arg ptr (side effect).
*/
while ((*p != EOS) && (*p == ' ' || *p == '\t'))
++p;
return (p);
}
/*------------------------------*/
/* skipwd */
/*------------------------------*/
char *skipwd (p)
REGISTER char *p;
{
/*
* skip over word and punctuation. anything but space,\t,\r,\n, and EOS
* is skipped. return ptr to the first of these found. also increments
* the arg ptr (side effect).
*/
while (*p != EOS && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
++p;
return (p);
}
/*------------------------------*/
/* space */
/*------------------------------*/
void space (n)
int n;
{
/*
* space vertically n lines. this does header and footer also.
*/
robrk ();
if (pg.lineno > pg.bottom)
return;
if (pg.lineno == 0)
phead ();
skip (min (n, pg.bottom + 1 - pg.lineno));
pg.lineno += n;
set_ireg ("ln", pg.lineno, 0);
if (pg.lineno > pg.bottom)
pfoot ();
}
/*------------------------------*/
/* getfield */
/*------------------------------*/
char *getfield (p, q, delim)
REGISTER char *p;
REGISTER char *q;
char delim;
{
/*
* get field from title
*/
while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS)
{
*q++ = *p++;
}
*q = EOS;
if (*p == delim)
++p;
return (p);
}
/*------------------------------*/
/* getwrd */
/*------------------------------*/
int getwrd (p0, p1)
REGISTER char *p0;
REGISTER char *p1;
{
/*
* get non-blank word from p0 into p1.
* return number of characters processed.
*/
REGISTER int i;
REGISTER char *p;
char c;
/*
* init counter...
*/
i = 0;
/*
* skip leading whitespace
*/
while (*p0 && (*p0 == ' ' || *p0 == '\t'))
{
++i;
++p0;
}
/*
* set ptr and start to look for end of word
*/
p = p0;
while (*p0 != ' ' && *p0 != EOS && *p0 != '\t')
{
if (*p0 == '\n' || *p0 == '\r')
break;
*p1 = *p0++;
++p1;
++i;
}
c = *(p1 - 1);
if (c == '\"')
c = *(p1 - 2);
if (c == '?' || c == '!')
{
*p1++ = ' ';
++i;
}
if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p)))
{
*p1++ = ' ';
++i;
}
*p1 = EOS;
return (i);
}
/*------------------------------*/
/* countesc */
/*------------------------------*/
#define ESC 27
int countesc (p)
REGISTER char *p;
{
/*
* count escape sequence characters in given null-terminated string.
* we try and interpret the escape sequence, and if we recognize it,
* we count the total number of chars in the sequence, including the
* ESC itself. e.g. "ESC [ 1 m" is 4. we do this for the entire string.
*
* the results are used when adjusting the margins, so we ignore the
* additional chars added. the escape sequence should not be broken
* up by this process, since we only add extra space(s) next to a
* space.
*/
REGISTER char *pp;
REGISTER int num;
/*
* initialize string pointer and count
*/
pp = p;
num = 0;
/*
* do entire string...
*/
while (*pp != EOS)